﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;

namespace Terminal.Advanced_AEUC_settings_controls.Scripting
{
    partial class ScriptSourcesify : Form
    {
        delegate void EmptyDelegate();

        ScrEditBox scrSourcesify;
        public ScriptSourcesify(ScrEditBox scrEdit)
        {
            scrSourcesify = scrEdit;
            InitializeComponent();
        }

        private void btnBind_Click(object sender, EventArgs e)
        {
            Button tmBtn = (Button)sender;
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Script files (*.scp)|*.scp|All files (*.*)|*.*";

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                if (tmBtn.Name == "btnBindA")
                {
                    tbScriptBoundA.Text = ofd.FileName;
                }
                else if (tmBtn.Name == "btnBindB")
                {
                    tbScriptBoundB.Text = ofd.FileName;
                }
                else if (tmBtn.Name == "btnBindC")
                {
                    tbScriptBoundC.Text = ofd.FileName;
                }
                else if (tmBtn.Name == "btnBindD")
                {
                    tbScriptBoundD.Text = ofd.FileName;
                }
                else if (tmBtn.Name == "btnBindE")
                {
                    tbScriptBoundE.Text = ofd.FileName;
                }
                else if (tmBtn.Name == "btnBindF")
                {
                    tbScriptBoundF.Text = ofd.FileName;
                }
                else if (tmBtn.Name == "btnBindG")
                {
                    tbScriptBoundG.Text = ofd.FileName;
                }
                else if (tmBtn.Name == "btnBindH")
                {
                    tbScriptBoundH.Text = ofd.FileName;
                }
                else if (tmBtn.Name == "btnBindI")
                {
                    tbScriptBoundI.Text = ofd.FileName;
                }
                else if (tmBtn.Name == "btnBindJ")
                {
                    tbScriptBoundJ.Text = ofd.FileName;
                }
            }
        }

        private void btnSourcesify_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;

            fBtns.Clear();
            fNames.Clear();
            fBtns.Add(tbButtonBoundA.Text);
            fNames.Add(tbScriptBoundA.Text);
            fBtns.Add(tbButtonBoundB.Text);
            fNames.Add(tbScriptBoundB.Text);
            fBtns.Add(tbButtonBoundC.Text);
            fNames.Add(tbScriptBoundC.Text);
            fBtns.Add(tbButtonBoundD.Text);
            fNames.Add(tbScriptBoundD.Text);
            fBtns.Add(tbButtonBoundE.Text);
            fNames.Add(tbScriptBoundE.Text);
            fBtns.Add(tbButtonBoundF.Text);
            fNames.Add(tbScriptBoundF.Text);
            fBtns.Add(tbButtonBoundG.Text);
            fNames.Add(tbScriptBoundG.Text);
            fBtns.Add(tbButtonBoundH.Text);
            fNames.Add(tbScriptBoundH.Text);
            fBtns.Add(tbButtonBoundI.Text);
            fNames.Add(tbScriptBoundI.Text);
            fBtns.Add(tbButtonBoundJ.Text);
            fNames.Add(tbScriptBoundJ.Text);

            Thread sourcesify = new Thread(new ThreadStart(generateCSource));
            sourcesify.IsBackground = true;
            sourcesify.Start();
        }

        void releaseCursor()
        {
            if (InvokeRequired)
            {
                Invoke(new EmptyDelegate(releaseCursor));
            }
            else
            {
                Cursor = Cursors.Default;
            }
        }

        Semaphore waitSourceGen = new Semaphore(0, 1);
        List<string> fBtns = new List<string>();
        List<string> fNames = new List<string>();

        public void sourceGenerated(string errorText)
        {
            waitSourceGen.Release();
        }

        #region Source file constants
        static string HEADER1 = "/* ==========================================================================\n" +
                                "*             Texas Instruments OMAP(TM) Platform Software\n" +
                                "*  (c) Copyright 2009, Texas Instruments Incorporated.  All Rights Reserved.\n" +
                                "*\n" +
                                "*  Use of this software is controlled by the terms and conditions found\n" +
                                "*  in the license agreement under which this software has been supplied.\n" +
                                "* =========================================================================== */\n" +
                                "/**\n" +
                                "* @file comm_lib_standalone.c\n" +
                                "*\n" +
                                "* Communication Layer Main Functions (UART comminication)\n" +
                                "*\n" +
                                "* @path WTSD_DucatiMMSW/framework/communication_layer/src/\n" +
                                "*\n" +
                                "* @rev 00.01\n" +
                                "*/\n" +
                                "/* -------------------------------------------------------------------------- */\n" +
                                "/* ----------------------------------------------------------------------------\n" +
                                "*!\n" +
                                "*! Revision History\n" +
                                "*! ===================================\n" +
                                "*! 13-07-2010: created.\n" +
                                "*!\n" +
                                "* =========================================================================== */\n" +
                                "\n" +
                                "/* User code goes here */\n" +
                                "/* ------compilation control switches --------------------------------------- */\n" +
                                "/****************************************************************\n" +
                                " * INCLUDE FILES\n" +
                                " ***************************************************************/\n" +
                                "/* ----- system and platform files ----------------------------*/\n" +
                                "/*-------program files ----------------------------------------*/\n" +
                                "/****************************************************************\n" +
                                "*  EXTERNAL REFERENCES NOTE: only use if not found in header file\n" +
                                "****************************************************************/\n" +
                                "/*--------data declarations -----------------------------------*/\n" +
                                "/*--------function prototypes ---------------------------------*/\n" +
                                "/****************************************************************\n" +
                                "*  PRIVATE DECLARATIONS Defined here, used only here\n" +
                                "****************************************************************/\n" +
                                "/*--------macros ----------------------------------------------*/\n" +
                                "#if 1\n" +
                                "#define SCREXEC_DBG_PRINT(x,...) MMS_IL_PRINT(x,__VA_ARGS__)\n" +
                                "#else\n" +
                                "#define SCREXEC_DBG_PRINT(x,...)\n" +
                                "#endif\n" +
                                "/*--------data declarations -----------------------------------*/\n" +
                                "/*--------function prototypes ---------------------------------*/\n" + 
                                "/****************************************************************\n" + 
                                "*  PUBLIC DECLARATIONS Defined here, used elsewhere\n" + 
                                "****************************************************************/\n" + 
                                "/*--------data declarations -----------------------------------*/\n" + 
                                "/*--------function prototypes ---------------------------------*/\n" + 
                                "/* ========================================================================== */\n" + 
                                "/**\n" + 
                                "* @fn readMsg() TODO:\n" + 
                                "*\n" + 
                                "*  @see\n" + 
                                "*/\n" + 
                                "/* ========================================================================== */\n" + 
                                "static void readMsg(TIMM_OSAL_PTR pBuffer, TIMM_OSAL_U32 nNumBytes)\n" + 
                                "{\n" +
                                "\tTIMM_OSAL_U32 actSizeRead = 0;\n" +
                                "\tstatic systemMessage_t* tmpMsg = NULL;\n" + 
                                "\n" +
                                "\tif (!pBuffer){\n" +
                                "\t\tSCREXEC_DBG_PRINT(\"Invalid return buffer supplied!\\n\", NULL);\n" +
                                "\t\treturn TIMM_OSAL_ERR_PARAMETER;\n" +
                                "\t}\n" + 
                                "\n" +
                                "\tif(tmpMsg == NULL){\n" +
                                "\t\tif (TIMM_OSAL_ERR_NONE != TIMM_OSAL_ReadFromPipe(STAND1_Script_Execution_PipeO, &tmpMsg, sizeof(systemMessage_t*), &actSizeRead, TIMM_OSAL_SUSPEND)) {\n" +
                                "\t\t\tSCREXEC_DBG_PRINT(\"TIMM_OSAL_ReadFromPipe failed!\\n\", NULL);\n" +
                                "\t\t\treturn TIMM_OSAL_ERR_UNKNOWN;\n" +
                                "\t\t}\n" +
                                "\t}\n" + 
                                "\n" +
                                "\tif(actSizeRead != sizeof(systemMessage_t*)){\n" +
                                "\t\tSTAND1_DBG_PRINT(\"Requested %d bytes but read %d bytes\\n\", nNumBytes, actSizeRead);\n" +
                                "\t\treturn TIMM_OSAL_ERR_UNKNOWN;\n" +
                                "\t}\n" + 
                                "\n" +
                                "\tif(tmpMsg == NULL){\n" +
                                "\t\tSCREXEC_DBG_PRINT(\"Non-existent message!\\n\", NULL);\n" +
                                "\t\treturn TIMM_OSAL_ERR_UNKNOWN;\n" +
                                "\t}\n" + 
                                "\n" +
                                "\tTIMM_OSAL_Memcpy(pBuffer, tmpMsg, sizeof(systemMessage_t));\n" + 
                                "\n" +
                                "\tif(tmpMsg->nPayloadSize == 0){\n" +
                                "\t\tSCREXEC_DBG_PRINT(\"Successful message read!\\nRead %08X\", &tmpMsg);\n" +
                                "\t\tTIMM_OSAL_Free(tmpMsg);\n" +
                                "\t\ttmpMsg = NULL;\n" +
                                "\t}else {\n" +
                                "\t\t((systemMessage_t*)pBuffer)->pPayload = TIMM_OSAL_MallocExtn(tmpMsg->nPayloadSize, TIMM_OSAL_TRUE, 32, 0, NULL);\n" +
                                "\t\tTIMM_OSAL_Memcpy(((systemMessage_t*)pBuffer)->pPayload, tmpMsg->pPayload, tmpMsg->nPayloadSize);\n" + 
                                "\n" +
                                "\t\tSCREXEC_DBG_PRINT(\"Successful message read!\\nRead %08X\", &tmpMsg);\n" +
                                "\t\tTIMM_OSAL_Free(tmpMsg->pPayload);\n" +
                                "\t\tTIMM_OSAL_Free(tmpMsg);\n" +
                                "\t\ttmpMsg = NULL;\n" +
                                "\t}\n" + 
                                "\n" +
                                "\treturn TIMM_OSAL_ERR_NONE;\n" + 
                                "}\n" + 
                                "\n" + 
                                "/* ========================================================================== */\n" + 
                                "/**\n" + 
                                "* @fn writeMsg() TODO:\n" + 
                                "*\n" + 
                                "*  @see\n" + 
                                "*/\n" + 
                                "/* ========================================================================== */\n" + 
                                "static void writeMsg(TIMM_OSAL_PTR pBuffer, TIMM_OSAL_U32 nNumBytes)\n" + 
                                "{\n" + 
                                "\tstatic systemMessage_t* tmpMsg = NULL;\n" + 
                                "\n" + 
                                "\tif (!pBuffer){\n" + 
                                "\t\tSCREXEC_DBG_PRINT(\"Invalid return buffer supplied!\\n\", NULL);\n" + 
                                "\t\treturn TIMM_OSAL_ERR_PARAMETER;\n" + 
                                "\t}\n" + 
                                "\n" + 
                                "\tif(nNumBytes == sizeof(systemMessage_t*)){\n" + 
                                "\t\ttmpMsg = TIMM_OSAL_MallocExtn(sizeof(systemMessage_t), TIMM_OSAL_TRUE, 32, 0, NULL);\n" + 
                                "\t\tTIMM_OSAL_Memcpy(tmpMsg, pBuffer, sizeof(systemMessage_t));\n" + 
                                "\t\tif(tmpMsg->nPayloadSize > 0){\n" +
                                "\t\t\ttmpMsg->pPayload = TIMM_OSAL_MallocExtn(tmpMsg->nPayloadSize, TIMM_OSAL_TRUE, 32, 0, NULL);\n" + 
                                "\t\t\tTIMM_OSAL_Memcpy(tmpMsg->pPayload, ((systemMessage_t*)pBuffer)->pPayload, tmpMsg->nPayloadSize);\n" + 
                                "\t\t}else {\n" + 
                                "\t\t\ttmpMsg->pPayload = NULL;\n" + 
                                "\t\t}\n" + 
                                "\t\tif (TIMM_OSAL_ERR_NONE != TIMM_OSAL_WriteToPipe(STAND1_Script_Execution_PipeI, &tmpMsg, sizeof(systemMessage_t*), TIMM_OSAL_SUSPEND)){\n" + 
                                "\t\t\tSCREXEC_DBG_PRINT(\"TIMM_OSAL_WriteToPipe failed!\\n\", NULL);\n" + 
                                "\t\t\treturn TIMM_OSAL_ERR_UNKNOWN;\n" + 
                                "\t\t}\n" + 
                                "\t\tSCREXEC_DBG_PRINT(\"Successful message write!\\nSent %08X\", &tmpMsg);\n" + 
                                "\t}else {\n" + 
                                "\t\tSCREXEC_DBG_PRINT(\"Out of sequence message!\\n\", NULL);\n" + 
                                "\t\treturn TIMM_OSAL_ERR_UNKNOWN;\n" + 
                                "\t}\n" + 
                                "\n" + 
                                "\treturn TIMM_OSAL_ERR_NONE;\n" + 
                                "}\n";

        static string HEADER2 = "/* ========================================================================== */\n" +
                                "/**\n" +
                                "* @fn Script_Execution_Thread() TODO:\n" +
                                "*\n" +
                                "*  @see\n" +
                                "*/\n" +
                                "/* ========================================================================== */\n" +
                                "TIMM_OSAL_ERRORTYPE Script_Execution_Thread(TIMM_OSAL_U32 nArgc, TIMM_OSAL_PTR pArgv)\n" +
                                "{\n" +
                                "\tSCREXEC_DBG_PRINT(\"Starting thread with %d aruments\\n\", nArgc);\n" +
                                "\tFILE* kbd = fopen(\"/dev/tty0\", \"r\");\n" +
                                "\n" +
                                "\tscrMod_InitMessages();\n" +
                                "\twhile(TIMM_OSAL_TRUE){\n" +
                                "\t\tTIMM_OSAL_U8 keypress;\n\n" +
                                "\t\tSCREXEC_DBG_PRINT(\"\\nWaiting for user input...\\n\\n\", NULL);\n\n" +
                                "\t\tfscanf(kbd, \"%c\", &keypress);\n\n";
                                
        static string HEADER3 = "\t}\n" + 
                                "}\n";
        #endregion

        void generateCSource()
        {
            FileInfo finf;
            string c_source = HEADER1;
            List<string> bindCalls = new List<string>();

            DirectoryInfo sourceGenMainDir = null;
            try
            {
                sourceGenMainDir = new DirectoryInfo(ScriptModule.Properties.Settings.Default.FastScriptMenuFolder + "\\source gen");
            }
            catch
            {
                sourceGenMainDir = new DirectoryInfo(Application.StartupPath + "\\source gen");
            }
            if (!sourceGenMainDir.Exists)
                sourceGenMainDir.Create();

            DirectoryInfo sourceGenScriptDir = new DirectoryInfo(sourceGenMainDir + "\\func");
            if (!sourceGenScriptDir.Exists)
                sourceGenScriptDir.Create();
            
            c_source += "#include \"func/scrMod_InitMessages.c\"\n";

            for (int i = 0; i < fNames.Count; i++)
            {
                try
                {
                    finf = new FileInfo(fNames[i]);
                    if (finf.Exists)
                    {
                        c_source += "#include \"func/scrMod_" + finf.Name.Replace(finf.Extension, ".c") + "\"\n";

                        bindCalls.Add("\t\tif(keypress == '" + fBtns[i] + "'){\n\t\t\tscrMod_" + finf.Name.Replace(finf.Extension, "") + "_exec();\n\t\t}\n");

                        scrSourcesify.LoadScriptFile(finf);
                        scrSourcesify.ScriptSourcesify(finf.Name.Replace(finf.Extension, ""));
                        waitSourceGen.WaitOne();

                        TextWriter txWr = new StreamWriter((new FileInfo(sourceGenScriptDir.FullName + "\\scrMod_" + finf.Name.Replace(finf.Extension, ".c"))).Create());
                        txWr.Write(scrSourcesify.ScriptCSourceGet().Replace("\t", "    "));
                        txWr.Close();
                    }
                }
                catch
                {
                }
            }

            c_source += HEADER2;

            for (int i = 0; i < bindCalls.Count; i++)
            {
                c_source += bindCalls[i];
            }

            c_source += HEADER3;

            TextWriter txMSGInitWr = new StreamWriter((new FileInfo(sourceGenScriptDir.FullName + "\\scrMod_InitMessages.c").Create()));
            txMSGInitWr.Write(scrSourcesify.ScriptMSGSourceGet().Replace("\t","    "));
            txMSGInitWr.Close();

            TextWriter txMainWr = new StreamWriter((new FileInfo(sourceGenMainDir.FullName + "\\script_exec_thread.c")).Create());
            txMainWr.Write(c_source.Replace("\t", "    "));
            txMainWr.Close();

            releaseCursor();
            MessageBox.Show("Source generation complete");
        }
    }
}
